home *** CD-ROM | disk | FTP | other *** search
/ The Programmer Disk / The Programmer Disk (Microforum).iso / xpro / c3 / pro2 / serial.h < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-27  |  5.9 KB  |  230 lines

  1. /*---------------------------------------------------------------------*
  2.    FILENAME:                     SERIAL.H
  3.  
  4.                   Some definitions used by SERIAL.C
  5.  
  6.  *--------------------------------------------------------------------*/
  7.  
  8. #define COM1            1
  9. #define COM2            2
  10. #define COM1BASE        0x3F8   /*  Base port address for COM1  */
  11. #define COM2BASE        0x2F8   /*  Base port address for COM2  */
  12.  
  13. /*
  14.     The 8250 UART has 10 registers accessible through 7 port addresses.
  15.     Here are their addresses relative to COM1BASE and COM2BASE. Note
  16.     that the baud rate registers, (DLL) and (DLH) are active only when
  17.     the Divisor-Latch ccess-Bit (DLAB) is on. The (DLAB) is bit 7 of
  18.     the (LCR).
  19.  
  20.     o TXR Output data to the serial port.
  21.     o RXR Input data from the serial port.
  22.     o LCR Initialize the serial port.
  23.     o IER Controls interrupt generation.
  24.     o IIR Identifies interrupts.
  25.     o MCR Send contorl signals to the modem.
  26.     o LSR Monitor the status of the serial port.
  27.     o MSR Receive status of the modem.
  28.     o DLL Low byte of baud rate divisor.
  29.     o DHH Hefine ASCII           0x007F  // Mask ASCII characters
  30. #define SBUFSIZ         0x4000  // Serial buffer size
  31.  
  32. int            SError          = NOERROR;
  33. int            portbase        = 0;
  34.  
  35. // A user defined type for use with getvect() & setvect()
  36. typedef void interrupt far (*intvect)(...);
  37.  
  38. intvect              oldvects[2];
  39.  
  40. static   char  ccbuf[SBUFSIZ];
  41. unsigned int   startbuf        = 0;
  42. unsigned int   endbuf          = 0;
  43.  
  44. /*-------------------------------------------------------------------
  45.      com_int - Handle communications interrupts and put them in ccbuf
  46. */
  47.  
  48. void interrupt com_int(void) {
  49.     disable();
  50.     if ((inportb(portbase + IIR) & RX_MASK) == RX_ID) {
  51.         if (((endbuf + 1) & SBUFSIZ - 1) == startbuf)
  52.             SError = BUFOVFL;
  53.  
  54.             ccbuf[endbuf++] = inportb(portbase + RXR);
  55.             endbuf &= SBUFSIZ - 1;
  56.     }
  57.  
  58.     // Signal end of hardware interrupt
  59.     outportb(ICR, EOI);
  60.     enable();
  61. } // end of com_int()
  62.  
  63. /*-------------------------------------------------------------------
  64.     SerialOut - Output a character to the serial port
  65. */
  66.  
  67. int SerialOut(char x) {
  68.     long int timeout = 0x0000FFFFL;
  69.  
  70.     outportb(portbase + MCR,  MC_INT | DTR | RTS);
  71.  
  72.     // Wait for Clear To Send from modem
  73.     while ((inportb(portbase + MSR) & CTS) == 0)
  74.         if (!(--timeout))
  75.             return (-1);
  76.  
  77.         timeout = 0x0000FFFFL;
  78.  
  79.         // Wait for transmitter to clear
  80.         while ((inportb(portbase + LSR) & XMTRDY) == 0)
  81.             if (!(--timeout))
  82.                 return (-1);
  83.  
  84.         disable();
  85.         outportb(portbase + TXR, x);
  86.         enable();
  87.  
  88.         return (0);
  89. } // end of serialOut()
  90.  
  91. /*-------------------------------------------------------------------
  92.      SerialString - Output a string to the serial port
  93. */
  94.  
  95. void SerialString(char *string) {
  96.     while (*string)
  97.         SerialOut(*string++);
  98. } // end of SerailString()
  99.  
  100. /*-------------------------------------------------------------------
  101.      getccb - This routine returns the current value in the buffer
  102. */
  103.  
  104. int getccb(void) {
  105.     int res;
  106.  
  107.     if (endbuf == startbuf)
  108.         return (-1);
  109.  
  110.     res = (int) ccbuf[startbuf++];
  111.     startbuf %= SBUFSIZ;
  112.     return (res);
  113. } // end of getccb()
  114.  
  115. /*-------------------------------------------------------------------
  116.      setvects - Install our functions to handle communications
  117. */
  118.  
  119. void setvects(void) {
  120.     oldvects[0] = (intvect) getvect(0x0B);
  121.     oldvects[1] = (intvect) getvect(0x0C);
  122.     setvect(0x0B, (intvect)com_int);
  123.     setvect(0x0C, (intvect)com_int);
  124. } // end of setvects()
  125.  
  126. /*-------------------------------------------------------------------
  127.      resvects - Uninstall our vectors before exiting the program
  128. */
  129.  
  130. void resvects(void) {
  131.     setvect(0x0B, (intvect)oldvects[0]);
  132.     setvect(0x0C, (intvect)oldvects[1]);
  133. } // end of resvects()
  134.  
  135. /*-------------------------------------------------------------------
  136.      i_enable - Turn on communications interrupts
  137. */
  138.  
  139. void i_enable(int pnum) {
  140.     int c;
  141.  
  142.     disable();
  143.     c = inportb(portbase + MCR) | MC_INT;
  144.     outportb(portbase + MCR, c);
  145.     outportb(portbase + IER, RX_INT);
  146.     c = inportb(IMR) & (pnum == COM1 ? IRQ4 : IRQ3);
  147.     outportb(IMR, c);
  148.     enable();
  149. } // end of i_enable()
  150.  
  151. /*-------------------------------------------------------------------
  152.         i_disable - Turn off communications interrupts
  153. */
  154.  
  155. void i_disable(void) {
  156.     int c;
  157.  
  158.     disable();
  159.     c = inportb(IMR) | ~IRQ3 | ~IRQ4;
  160.     outportb(IMR, c);
  161.     outportb(portbase + IER, 0);
  162.     c = inportb(portbase + MCR) & ~MC_INT;
  163.     outportb(portbase + MCR, c);
  164.     enable();
  165. } // end of i_disable()
  166.  
  167. /*-------------------------------------------------------------------
  168.      comm_on - Tell modem that we're ready to go
  169. */
  170.  
  171. void comm_on(void) {
  172.     int c, pnum;
  173.  
  174.     pnum = (portbase == COM1BASE ? COM1 : COM2);
  175.     i_enable(pnum);
  176.     c = inportb(portbase + MCR) | DTR | RTS;
  177.     outportb(portbase + MCR, c);
  178. } // end of comm_on()
  179.  
  180. /*-------------------------------------------------------------------
  181.      comm_off - Go off-line
  182. */
  183.  
  184. void comm_off(void) {
  185.     i_disable();
  186.     outportb(portbase + MCR, 0);
  187. } // end of comm_off()
  188.  
  189. /*-------------------------------------------------------------------
  190.      initserial -
  191. */
  192.  
  193. void initserial(void) {
  194.     endbuf = startbuf = 0;
  195.     setvects();
  196.     comm_on();
  197. } // end of initserial()
  198.  
  199. /*-------------------------------------------------------------------
  200.      closeserial -
  201. */
  202.  
  203. void closeserial(void) {
  204.     comm_off();
  205.     resvects();
  206. } // end of closerial()
  207.  
  208. /*-------------------------------------------------------------------
  209.      SetPort - Set the port number to use
  210. */
  211.  
  212. int SetPort(int Port) {
  213.     int Offset, far *RS232_Addr;
  214.  
  215.     switch (Port) { // Sort out the base address
  216.         caserupt only if it
  217.     is not masked (FALSE).
  218. */
  219. #define IRQ3            0xF7  /* COM2 */
  220. #define IRQ4            0xEF  /* COM1 */
  221. pt */
  222.  
  223.  
  224. /*
  225.     The (IMR) tells the (PIC) to service an interrupt only if it
  226.     is not masked (FALSE).
  227. */
  228. #define IRQ3            0xF7  /* COM2 */
  229. #define IRQ4            0xEF  /* COM1 */
  230.